 #include <wx/app.h>
 #include <wx/dcscreen.h>
 #include <wx/dcmemory.h>
 #include <wx/checkbox.h>
 #include <wx/dir.h>
 #include <wx/uri.h>
 #include <wx/log.h>
 #include <wx/intl.h>
 #include <wx/font.h>
 #include <wx/icon.h>
 #include <wx/menu.h>
 #include <wx/utils.h>
 #include <wx/panel.h>
 #include <wx/frame.h>
 #include <wx/image.h>
 #include <wx/sizer.h>
 #include <wx/sound.h>
 #include <wx/string.h>
 #include <wx/bitmap.h>
 #include <wx/gdicmn.h>
 #include <wx/colour.h>
 #include <wx/choice.h>
 #include <wx/splash.h>
 #include <wx/base64.h>
 #include <wx/tokenzr.h>
 #include <wx/filesys.h>
 #include <wx/statbmp.h>
 #include <wx/mstream.h>
 #include <wx/textfile.h>
 #include <wx/stattext.h>
 #include <wx/textctrl.h>
 #include <wx/filename.h>
 #include <wx/stdpaths.h>
 #include <wx/statline.h>
 #include <wx/combobox.h>
 #include <wx/popupwin.h>
 #include <wx/button.h>
 #include <wx/dcclient.h>
 #include <wx/splitter.h>
 #include <wx/dialog.h>
 #include <wx/notifmsg.h>
 #include <wx/wrapsizer.h>
 #include <wx/taskbar.h>
 #include <wx/richtext/richtextctrl.h>
 #include <wx/overlay.h>
 #include <wx/radiobut.h>

 #include <xpm/hand.xpm>
 #include <xpm/checkdim.xpm>
 #include <xpm/check.xpm>
 #include <xpm/snip.xpm>
 #include <xpm/snip2.xpm>
  
 #define POPUP_BUDDY_TAG          5000
 #define POPUP_BUDDY_AUTOREPLY    5001
 #define POPUP_BUDDY_HIDE         5002
 #define POPUP_BUDDY_BLOCK        5003

 #define TIMER_BALOON             6001

 #define POPUP_PRESENCE_AVAILABLE 6008
 #define POPUP_PRESENCE_AWAY      6009
 #define POPUP_PRESENCE_BUSY      6010
 #define POPUP_PRESENCE_INVISIBLE 6011
 #define POPUP_PRESENCE_LOGOUT    6012

 #define POPUP_MAIN_NEW           6013 
 #define POPUP_MAIN_COLOUR        6014
 #define POPUP_MAIN_ABOUT         6015
 #define POPUP_MAIN_EXIT          6016

 #define POPUP_SHOW_ONLINE        6017
 #define POPUP_REFRESH_ROSTER     6018
 #define POPUP_STATUS_ALERTS      6019
 #define POPUP_HIDE_TITLE         6020
 #define POPUP_TITLE_SESSION      6021

 #define PU_SIN       POPUP_STATUS_ALERTS + 1
 #define PU_SOUT      POPUP_STATUS_ALERTS + 2
 #define PU_OPEN      POPUP_STATUS_ALERTS + 3
 #define PU_EXIT      POPUP_STATUS_ALERTS + 4

 struct IMBuddy;

 ///////////////////////////////////////////////////////////////////////////////
 /// Class QEdit
 ///////////////////////////////////////////////////////////////////////////////

 class QEdit : public wxTextCtrl 
 {
   public:

    wxWindow  *toRestore;
    wxSizer   *sizer;

    QEdit(wxWindow *parent, 
           wxWindowID id, 
           const wxString &value=wxEmptyString, 
           const wxPoint &pos=wxDefaultPosition, 
           const wxSize &size=wxDefaultSize, 
           long style=0, 
           const wxValidator &validator=wxDefaultValidator,
           const wxString &name=wxTextCtrlNameStr);

   void QEdit_Hide(void);
   void OnKeyDown(wxKeyEvent&);
 };

 ///////////////////////////////////////////////////////////////////////////////
 /// Class QText
 ///////////////////////////////////////////////////////////////////////////////

 class QText : public wxStaticText
 {
   public:
    wxString m_label;
    void OnEraseBackGround(wxEraseEvent&);
    void OnPaint(wxPaintEvent&);
    void SetLabel(const wxString& label);

    QText(wxWindow*,
          wxWindowID,
          const wxString&,
          const wxPoint&,
          const wxSize& size = wxDefaultSize,
          long style = 0,
          const wxString& name = wxEmptyString);
 };

 ///////////////////////////////////////////////////////////////////////////////
 /// Class QBitmap
 ///////////////////////////////////////////////////////////////////////////////

 class QBitmap : public wxStaticBitmap
 {
   public:

    void        *m_data; /* IMBuddy */

    void OnPopup (wxMouseEvent&);
    void OnEnterWindow (wxMouseEvent&); 
    void OnLeaveWindow (wxMouseEvent&);
    void OnLeftDown (wxMouseEvent&);
    void OnLeftDClick (wxMouseEvent&);
    void OnLeftUp (wxMouseEvent&);
    void OnRightUp (wxMouseEvent&);
    void OnMotion (wxMouseEvent&);
    void OnEraseBackGround (wxEraseEvent&);
    void OnPaint (wxPaintEvent&);
    void OnMouseCaptureLost(wxMouseCaptureLostEvent&);

    QBitmap(wxWindow*,
            wxWindowID,
            const wxBitmap&,
            const wxPoint&,
            const wxSize&,
            long  style,
            const wxString&);
 };

 ///////////////////////////////////////////////////////////////////////////////
 /// Class QTab
 ///////////////////////////////////////////////////////////////////////////////

 class QTab : public wxWindow
 {
   public:

    const char  ** m_bitmap;
    wxPen        * m_highlight;    /* pen used for hilighting the tab */
    wxColour       m_textcolour;
    wxColour       m_textcolourhighlight;
    bool           m_direction;    /* 1 - image left, text right */
    bool           m_alert;        
    bool           m_active;
    bool           m_round;
    bool           m_underline;
    bool           m_check;
    void         * m_data;
    bool           bStartSnip;

    wxPoint        m_anchorpoint;
    wxPoint        m_currentpoint;
    wxOverlay      m_overlay;
    
    QTab() {}

    QTab(wxWindow          *parent,
          wxWindowID        id     = wxID_ANY,
          const wxPoint&    pos    = wxDefaultPosition,
          const wxSize&     size   = wxDefaultSize,
          long              style  = 0|wxTRANSPARENT_WINDOW, 
          const wxString&   txt    = wxEmptyString,
          const char      **bitmap = NULL, 
          const wxString&   name   = wxEmptyString, 
          bool              direction = true)
        : wxWindow (parent, id, pos, size, style) 
        { 
           m_bitmap     = bitmap;
           m_direction  = direction;
           m_highlight  = 0;
           m_active     = true;
           m_alert      = false;
           m_underline  = false;
           m_round      = true;
           m_textcolour = *wxBLACK;           
           m_data       = NULL;
           bStartSnip   = false;

           SetLabel(txt);
           SetName(name);

           SetCursor(wxCursor(wxImage(hand_xpm)));

	       this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(QTab::OnEnterWindow), NULL, this);
	       this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(QTab::OnLeaveWindow), NULL, this);
	       this->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(QTab::OnKillFocus), NULL, this);
	       this->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(QTab::OnSetFocus), NULL, this);
           this->Connect(wxEVT_CHAR, wxKeyEventHandler(QTab::OnChar), NULL, this);
           this->Connect(wxEVT_MOTION, wxMouseEventHandler(QTab::OnMotion));
           this->Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(QTab::OnMouseCaptureLost), NULL, this);
        }

    void   OnMouseCaptureLost(wxMouseCaptureLostEvent&);
    wxSize DoGetBestSize() const;
    void   Render(wxDC&);
    void   OnPaint(wxPaintEvent&);
    void   SetLabel(const wxString&);
    void   OnRightDown(wxMouseEvent&);
    void   OnLeftDown(wxMouseEvent&);
    void   OnLeftUp(wxMouseEvent&);
    void   mouseWheelMoved(wxMouseEvent&);
    void   rightClick(wxMouseEvent&);
    void   keyPressed(wxKeyEvent&);
    void   keyReleased(wxKeyEvent&);
    void   OnEraseBackground(wxEraseEvent&);
    void   OnPopup(wxMouseEvent&);
    void   OnEnterWindow(wxMouseEvent&);
    void   OnLeaveWindow(wxMouseEvent&);
    void   OnKillFocus(wxFocusEvent&);
    void   OnSetFocus(wxFocusEvent&);
    void   OnChar(wxKeyEvent& e);
    void   OnMotion (wxMouseEvent&);

    DECLARE_EVENT_TABLE();
 };
 
 //////////////////////////////////////////////////////////////////////////
 /// class Qlist
 //////////////////////////////////////////////////////////////////////////

 class Qlist : public wxScrolledWindow
 {
   public:

     wxWrapSizer     * szWrap;
     void            * m_autoreply;
     int               l_count;

     Qlist(wxWindow       *parent,
           wxWindowID      id = wxID_ANY,
           const wxPoint&  pos = wxDefaultPosition,
           const wxSize&   size = wxDefaultSize,
           long            style = wxVSCROLL|wxNO_BORDER);

    ~Qlist();

    wxSize DoGetBestSize() const;
    int    InsertItem (wxString&, wxString, wxString&, const char **);
    void   DeleteItem (int);
    void   DeleteAllItems (void *key = NULL);
    void * GetItemData (int);
    void   SetItemData (int, void *) ;
    int    GetItemCount();
    void   SetItemImage (int, const char **, wxImage *);
    void   SetItemTip (int, wxString&);
    void   SetItemText (int, wxString&, int);
    void   SetItemTextColour (int, wxColour&, int);
    void   SetItemStatusImage (int index, const char **status = 0, wxString *resource = 0);
    void   HideItem (int);
    void   ShowItem (int x, bool bLayout = true);
    void   OnRightUp (wxMouseEvent&);
    void   OnPopup (wxMouseEvent&);
    void   OnLeftDown (wxMouseEvent&);
 };

 //////////////////////////////////////////////////////////////////////////
 /// class AutoReply
 //////////////////////////////////////////////////////////////////////////

 class AutoReply : public wxDialog
 {
  public:
    wxBoxSizer        * bszTitle;
    wxPoint             m_delta;
    wxTextCtrl        * m_message;
    wxCheckBox        * m_checkAll;
    wxButton          * m_button;

    void OnAutoReply (wxCommandEvent& e);
    void OnLeftUp (wxMouseEvent& WXUNUSED(e));
    void OnPaint (wxPaintEvent& e);
    void OnLeftDown (wxMouseEvent& e);
    void OnMotion (wxMouseEvent& e);

    ~AutoReply();

    AutoReply(wxWindow* parent, 
              wxWindowID id = wxID_ANY, 
              const wxString& title = wxEmptyString, 
              const wxPoint& pos = wxDefaultPosition, 
              const wxSize& size = wxSize(250,204), 
              long style = wxCLIP_CHILDREN|wxNO_BORDER|wxTAB_TRAVERSAL);
 };

 ///////////////////////////////////////////////////////////////////////////////
 /// Class QLine
 ///////////////////////////////////////////////////////////////////////////////

 class QLine : public wxWindow
 {
   public:

    int thick;

    void OnEraseBackground(wxEraseEvent&);
    void OnPaint(wxPaintEvent& WXUNUSED(e));
    wxSize DoGetBestSize() const;

    QLine(wxWindow  *parent,
           wxWindowID id = wxID_ANY,
           const wxPoint& pos = wxDefaultPosition,
           const wxSize& size = wxDefaultSize,
           long style = 0|wxTRANSPARENT_WINDOW, int thick = 1);

    QLine();

    DECLARE_EVENT_TABLE();
 };

 ///////////////////////////////////////////////////////////////////////////////
 /// Class ChatDialog
 ///////////////////////////////////////////////////////////////////////////////

 class ChatDialog : public wxFrame 
 {
   private:

    wxPoint      m_delta;
    
    void  OnClose(wxCloseEvent& e);
    void  OnLeftDClick(wxMouseEvent& WXUNUSED(e));
    void  OnLeftUp(wxMouseEvent& WXUNUSED(e));
    void  OnPaint(wxPaintEvent& e);
    void  OnLeftDown(wxMouseEvent& e);
    void  OnMotion(wxMouseEvent& e);
    void  OnKeyDown(wxKeyEvent&);
    void  OnKillFocus(wxFocusEvent&);
	void  OnSetFocus(wxFocusEvent&);
        
   public:

    wxPoint             m_point;   
    wxBoxSizer        * bSizer1;
    wxBoxSizer        * bSizer2;
    wxBoxSizer        * bSizer3;
    wxBoxSizer        * bSizer4;
    QTab              * ch_menu;
    QTab              * m_snip;
    QBitmap           * ch_minus;
    QBitmap           * ch_close;
    wxStaticBitmap    * ch_avatar;
    QText             * ch_fn;
    wxStaticText      * ch_fid;
    QBitmap           * ch_status;
    wxSplitterWindow  * ch_splitter;
    wxPanel           * ch_up;
    wxRichTextCtrl    * ch_transcript;
    wxPanel           * ch_down;
    wxRichTextCtrl    * ch_chat;
    void              * jabber;
    IMBuddy           * buddy;


    void  c_splitterOnIdle(wxIdleEvent&);
    void  parse_chat_transcript(wxString line = wxEmptyString);
    void  OnTextEnter(wxCommandEvent&);

    ChatDialog(wxWindow* parent,
               wxWindowID id = wxID_ANY,
               const wxString& title = wxEmptyString,
               const wxPoint& pos = wxDefaultPosition,
               const wxSize& size = wxDefaultSize,
               long style = 0,
               IMBuddy *buddy = 0, void *jabber = 0); 

    ~ChatDialog();
 };

 /////////////////////////////////////////////////////////////////////////////
 // TransientPopup
 /////////////////////////////////////////////////////////////////////////////

 class TransientPopup: public wxPopupTransientWindow
 {
   public:

    TransientPopup( wxWindow *parent, wxString msg, char type );
    virtual ~TransientPopup();
    virtual void Popup(wxWindow *focus = NULL);
    virtual void OnDismiss();
    virtual bool Show(bool show = true );
    virtual bool ProcessLeftDown(wxMouseEvent&);

   private:

    void OnSetFocus(wxFocusEvent&);
    void OnKillFocus(wxFocusEvent&);

    wxScrolledWindow  * m_panel;
    QText             * m_text;
    wxBoxSizer        * topSizer;

    DECLARE_CLASS(TransientPopup)
    DECLARE_EVENT_TABLE()
 };


 //////////////////////////////////////////////////////
 // Taskbar icon 
 //////////////////////////////////////////////////////

 class TBIcon : public wxTaskBarIcon
 {
   public:
    #if defined(__WXOSX__) && wxOSX_USE_COCOA
      TBIcon(wxTaskBarIconType iconType = DEFAULT_TYPE)
      :   wxTaskBarIcon(iconType)
    #else
      TBIcon()
    #endif
      {}

    void OnSignOut (wxCommandEvent&);
    void OnOpen (wxCommandEvent&);
    void OnExit (wxCommandEvent&);
    void OnLeftDClick (wxTaskBarIconEvent&);

    virtual wxMenu *CreatePopupMenu();

    DECLARE_EVENT_TABLE()
 };

 class TaskBarBaloon : public wxFrame
 {
   public:

      TaskBarBaloon(wxString sTitle, wxString sMessage);
      virtual ~TaskBarBaloon() { delete timer; }
 
      /** painting bg */
      void OnPaint(wxPaintEvent& event);
      /** timer to close window */
      void OnTimerTick(wxTimerEvent & event);
      /** click on the baloon */
      void OnClick(wxMouseEvent & event);
      /** display the baloon and run the timer */
      void showBaloon(unsigned int iTimeout);

   private:

      wxTimer * timer;
      unsigned int iTimeout;
      DECLARE_EVENT_TABLE();
 };

class SeeThroughFrame : public wxFrame
{
  public:
    SeeThroughFrame();

 private:
    enum State
    {
        STATE_SEETHROUGH,
        STATE_TRANSPARENT,
        STATE_OPAQUE,
        STATE_MAX
    };

    State m_currentState;

};


 
 
 
 void
  xml_entity_inbound (wxString&);

 void
  xml_entity_outbound (wxString&);
